package com.zhanghe.study.config;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * 读取解析配置信息，并返回处理后的Environment
 */
public class MyConfig {
    private static ClassLoader loader = ClassLoader.getSystemClassLoader();

    /**
     * 读取xml信息
     *
     * @param resource
     * @return
     */
    public Connection build(String resource) {
        Element element = getRoot(resource);
        return evalDataSource(element);
    }

    private Connection evalDataSource(Element node) {
        // 判断根节点是不是datasource
        if (node == null || !"datasource".equals(node.getName())) {
            throw new RuntimeException("根节点不是<datasource>");
        }
        String driverName = null;
        String url = null;
        String username = null;
        String password = null;
        //获取属性节点
        for (Object item : node.elements("property")) {
            Element element = (Element) item;
            String value = getValue(element);
            String name = element.attributeValue("name");
            if (name == null || value == null) {
                throw new RuntimeException("<datasource>节点中property的name或value不能为空");
            }
            if ("url".equals(name)) {
                url = value;
            } else if ("username".equals(name)) {
                username = value;
            } else if ("password".equals(name)) {
                password = value;
            } else if ("driverName".equals(name)) {
                driverName = value;
            }
        }

        // 建立连接
        try {
            Class.forName(driverName);
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(driverName + "未找到该驱动类");
        }
        Connection connection = null;
        try {
            connection = DriverManager.getConnection(url, username, password);
        } catch (SQLException e) {
            throw new RuntimeException("数据库连接失败");
        }
        return connection;
    }

    /**
     * 获取节点值
     * 如果有主体 读取主体  如果没有  读取 value属性
     *
     * @param node
     * @return
     */
    private String getValue(Element node) {
        if (node.hasContent()) {
            return node.getTextTrim();
        }
        return node.attributeValue("value");
    }

    /**
     * 解析mapper
     * @param path
     * @return
     */
    public MapperBean readMapper(String path) {
        MapperBean mapper = new MapperBean();
        Element element = getRoot(path);
        if(element.getName() == null || !"mapper".equals(element.getName())){
            throw new RuntimeException("根节点不是mapper");
        }
        // 找到所对应的接口
        if(element.attributeValue("nameSpace") == null || "".equals(element.attributeValue("nameSpace"))){
            throw new RuntimeException("请指定命名空间nameSpace属性");
        }
        // namespace 对应接口名
        mapper.setInterfaceName(element.attributeValue("nameSpace").trim());
        List<Function> list = new ArrayList<Function>();
        Iterator iterator = element.elementIterator();
        while(iterator.hasNext()){
            // 对应该接口的一个方法
            Function function = new Function();
            Element ele = (Element) iterator.next();
            //操作类型  select delete insert update
            String sqltype = ele.getName().trim();
            String methodName = ele.attributeValue("id").trim();
            // sql节点
            String sql = ele.getText().trim();
            // 返回类型
            String resultType = ele.attributeValue("resultType").trim();
            function.setSqltype(sqltype);
            function.setMethodName(methodName);
            Object newInstance = null;
            try {
                newInstance = Class.forName(resultType).newInstance();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
            function.setResultType(newInstance);
            function.setSql(sql);
            list.add(function);
        }
        mapper.setList(list);
        return mapper;
    }

    private Element getRoot(String path) {
        MapperBean mapper = new MapperBean();
        InputStream inputStream = loader.getResourceAsStream(path);
        SAXReader reader = new SAXReader();
        Document document = null;
        try {
            document = reader.read(inputStream);
        } catch (DocumentException e) {
            throw new RuntimeException("读取xml失败" + path);
        }
        Element element = document.getRootElement();
        return element;
    }


}
